home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BBS Toolkit
/
BBS Toolkit.iso
/
doors_1
/
doorskl3.zip
/
XBBSMSG.ZIP
/
GETABNCH.C
next >
Wrap
C/C++ Source or Header
|
1991-12-14
|
9KB
|
392 lines
/*
* Does 'threading', finds personal msgs, etc. very fast
* This is a "genericized" version of what HeadEdit uses
* There are a few functions in here available in other source
* I've released, such as rstrip, lstrip, stristr, etc.
* I'm including these at the bottom of this in case you
* don't already have them.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
#include <share.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "xmsg.h"
#ifdef DONTHAVE
char * _fastcall rstrip (char *a);
char * _fastcall lstrip (char *a);
char * _fastcall stripcr (char *a);
char * _fastcall stristr (char *t, char *s);
#endif
unsigned int _fastcall thread (int mode,USHORT cp,int which,
unsigned int messno,char *body,
XMSG *msg,MSGAREA *info);
unsigned int _fastcall get_abunch (int mode,USHORT cp,MSGAREA *info,
unsigned int messno,char type,
int direction,char *str,char *uname);
#define BUFMSGS 12
unsigned int _fastcall get_abunch (int mode,USHORT cp,MSGAREA *info,
unsigned int messno,char type,
int direction,char *str,char *uname) {
/*
* messno = message # to start at (usually current # or lmr setting)
*
* type = 0...personal message check (something to you that you
* haven't read yet)
* 1...subject check. find a matching subject. used for
* threading messages that have no MSGID/REPLY kludge.
* 2...body check. find a match in the msg body in the first
* 512 bytes (used for MSGID/REPLY).
*
* direction == -1 (reverse) or 1 (forward)
*
* str == string to match if type == 1 or type == 2
*
* returns 0 (no match) or msg # of match.
*/
XMSG msgs[BUFMSGS];
int handle,handle2,temp2,y;
char finished = 0,once,*p;
unsigned int temp,x = 0;
if(type && !str) return 0;
if(direction >= 0) {
messno++;
direction = 1;
}
else direction = -1;
{
char filename[24];
sprintf(filename,"./MSG/XDATA.%03x",info->number);
while ((handle = sopen(filename,O_NOINHERIT | O_RDONLY | O_BINARY, SH_DENYNO)) == -1) {
if (errno == EACCES) {
x++;
if(x > 10) {
return 0;
}
DosSleep(500L);
}
else {
return 0;
}
}
}
if(direction < 0) {
if(messno > BUFMSGS - 1) {
x = BUFMSGS;
messno -= BUFMSGS;
}
else {
x = messno - 1;
messno = 1;
}
}
else {
}
Loop:
DosSleep(1L);
memset(&msgs[0],0,sizeof(XMSG) * BUFMSGS);
if(direction > 0) {
x = (unsigned int)(filelength(handle) / (long)sizeof(XMSG));
if(messno > x || finished) {
close(handle);
return 0;
}
if((x - messno) < BUFMSGS - 1) x -= (messno - 1);
else x = BUFMSGS;
}
if ((lseek(handle,(long)((long)(messno - 1) * (long)sizeof(XMSG)),SEEK_SET) == -1) || ((temp = (read(handle,&msgs,(x * sizeof(XMSG))))) < 1)) {
close(handle);
return 0;
}
if((temp / sizeof(XMSG)) < x) x = temp / sizeof(XMSG);
if(direction < 0) y = x - 1;
else y = 0;
if(type == 0) { /* Personal mail check */
#ifdef DEBUG
printf("\r\nx=%u y=%u dir=%d",x,y,direction);
#endif
for(;;) {
if((msgs[y].xflags & MSGDELETED) || (msgs[y].fflags & MSGREAD)) goto NoGot;
#ifdef DEBUG
printf("\r\nx=%u y=%u dir=%d",x,y,direction);
#endif
rstrip(msgs[y].to);
if(*msgs[y].to) {
/* this could be expanded to check for multiple names */
if(!stricmp(msgs[y].to,uname)) goto GotIt;
}
else goto NoGot;
GotIt:
close(handle);
return (messno + y);
NoGot:
y += (direction);
if(direction < 0) {
if(y < 0) break;
}
else if(y >= (int)x) break;
}
}
else if (type == 1) { /* Subject check */
temp = strlen(str);
for(;;) {
if (msgs[y].xflags & MSGDELETED) goto NoGot2;
p = msgs[y].subj;
rstrip(p);
lstrip(p);
while(!strnicmp(p,"RE:",3)) {
p += 3;
while(*p == ' ') p++;
}
if(!*p) {
if(!*str) {
close(handle);
return (messno + y);
}
else {
goto NoGot2;
}
}
handle2 = min(24,temp);
handle2 = min(handle2,(int)strlen(p));
if(!strnicmp(p,str,handle2) || (!*p && !*str)) {
close(handle);
return (messno + y);
}
NoGot2:
y += (direction);
if(direction<0) {
if(y < 0) break;
}
else if(y >= (int)x) break;
}
}
else if (type == 2) { /* Body check */
if(!*str) {
close(handle);
return 0;
}
{
char filename[24];
sprintf(filename,"./MSG/XTEXT.%03x",info->number);
temp = 0;
while ((handle2 = sopen(filename,O_NOINHERIT | O_RDONLY | O_BINARY, SH_DENYNO)) == -1) {
if (errno == EACCES) {
temp++;
if (temp > 10) {
close(handle);
return 0;
}
DosSleep(500L);
}
else {
close(handle);
return 0;
}
}
}
for(;;) {
if(!msgs[y].length) goto NoGot3;
if ((msgs[y].xflags & MSGDELETED)) goto NoGot3;
once = 0;
while((lseek(handle2,msgs[y].start,SEEK_SET)) == -1L) {
if(once < 3) {
once++;
}
else {
goto NoGot3;
}
}
{
char buffer[514];
*buffer = 0;
temp2 = min(msgs[y].length - 1,512);
if(!DosRead(handle2,buffer,temp2,&temp)) {
buffer[temp + 1] = 0;
if(stristr(buffer,str)) {
close(handle);
close(handle2);
return (messno + y);
}
}
}
NoGot3:
y += (direction);
if(direction < 0) {
if(y < 0) break;
}
else if(y >= (int)x) break;
}
close(handle2);
}
if(direction > 0) {
if((long)messno + (long)x > 65535L) finished = 1;
else messno += x;
}
else {
if(messno == 1) {
close(handle);
return 0;
}
else {
if(messno <= x) messno = 1;
else messno -= x;
}
}
goto Loop;
}
unsigned int _fastcall thread (int mode,USHORT cp,int which,
unsigned int messno,char *body,
XMSG *msg,MSGAREA *info) {
/*
* performs threading forward or backward in an area.
* if which == 'B' threads backward, else threads forward.
* is smart enough to reverse at end/beginning of message.
* if body contains anything, it's used (MSGID/REPLY),
* else the msg->subj is matched.
* returns matching message # or 0 on no-match
*/
unsigned int nomess;
int direction;
XMSG msg2;
char *p;
nomess = how_many_msgs(info);
if (nomess <= 1) return 0;
if (messno >= nomess) which = 'B';
if (messno <= 1) which = 'F';
if (which != 'B' && which != 'F') which = 'F';
if(which == 'B') direction = (-1);
else direction = 1;
if(!body || !*body) {
p = msg->subj;
lstrip(p);
rstrip(p);
while(!strnicmp(p,"RE:",3)) {
p += 3;
while(*p == ' ') p++;
}
messno = get_abunch(mode,cp,info,messno,1,direction,p);
}
else {
messno = get_abunch(mode,cp,info,messno,2,direction,body);
}
/* note: you might want to check security on the message found... */
return messno;
}
#ifdef DONTHAVE
char * _fastcall rstrip (char *a) { /* strips trailing spaces */
register int x;
x = strlen(a);
while (x && a && a[x - 1] == ' ') a[--x] = 0;
return a;
}
char * _fastcall lstrip (char *a) { /* strips leading spaces */
register int x;
x = strlen(a);
while (x && *a == ' ') memmove (a,(a + 1),x--);
return (a);
}
char * _fastcall stripcr (char *a) { /* strips trailing cr/lfs */
register int x;
x = strlen(a);
while (x && (a[x - 1] == '\n' || a[x - 1] == '\r')) a[--x] = 0;
return a;
}
/* insensitive strstr() */
char * _fastcall stristr (char *t, char *s) {
char *t1;
char *s1;
while(*t) {
t1 = t;
s1 = s;
while(*s1) {
if (toupper(*s1) != toupper(*t)) break;
else {
s1++;
t++;
}
}
if (!*s1) return t1;
t = t1 + 1;
}
return NULL;
}
#endif